﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WhsFacebook.Net.Web.Database;

namespace WhsFacebook.Net.Web.Facebook.Controls
{
    [ToolboxData("<{0}:LogFacebookVisit runat=\"server\" />")]
    public class LogFacebookVisit : WebControl
    {
        private readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(LogFacebookVisit));

        public bool Authenticated
        {
            get; private set;
        }

        public bool IsLoggedIn
        {
            get;
            private set;
        }

        public long UserId
        {
            get;
            private set;
        }

        public long ViaUserId
        {
            get;
            private set;
        }

        public DateTime TimeStamp
        {
            get;
            private set;
        }

        public Guid? WhsInstanceId
        {
            get;
            private set;
        }

        public IEnumerable<long> FriendsUserIds
        {
            get;
            private set;
        }

        protected override void OnInit(EventArgs ee)
        {
            base.OnInit(ee);

            // log visit
            DoLog();
        }

        private void DoLog()
        {
            var context = this.Context;

            if (string.IsNullOrEmpty(FacebookConverter.ToString(context.Request.Params["fb_sig_time"])))
                throw new InvalidOperationException("This URL is to be called from Facebook only!");

            // gather all data
            var auth = FacebookConverter.ToBoolean(context.Request.Params["fb_sig_added"]);
            var loggedIn = !FacebookConverter.ToBoolean(context.Request.Params["fb_sig_logged_out_facebook"]);
            var ts = FacebookConverter.FromUnixTime(context.Request.Params["fb_sig_time"]);
            var viaUser = FacebookConverter.ToInt64(context.Request.Params["fb_sig_profile_user"]);
            var sid = FacebookConverter.ToString(context.Request.Params["fb_sig_session_key"]);
            var locale = FacebookConverter.ToString(context.Request.Params["fb_sig_locale"]);
            var uid = FacebookConverter.ToInt64(
                context.Request.Params["fb_sig_user"] ??
                context.Request.Params["fb_sig_canvas_user"]
                );

            var friends = (FacebookConverter.ToString(context.Request.Params["fb_sig_friends"]) ?? string.Empty).Split(',').Select(FacebookConverter.ToInt64);

            // has WHS instance id reference?
            var whs = this.Context.Request.Params["whs"];

            if (!string.IsNullOrEmpty(whs))
            {
                Guid g;

                if (Guid.TryParse(whs, out g))
                    this.WhsInstanceId = g;
            }

            // log
            try
            {
                using (var e = new WhsFacebookEntities())
                {
                    var ua = new DbUserVisitLog()
                    {
                        FacebookUserId = uid,
                        IsLoggedIn = loggedIn,
                        Occurrence = ts,
                        SessionId = sid,
                        ViaFacebookUserId = viaUser,
                        UserLocale = locale,
                        WhsInstanceId = this.WhsInstanceId,
                    };

                    foreach (var friend in friends)
                    {
                        ua.Friends.Add(new DbUserActionLogFriend()
                        {
                            FacebookUserId = uid,
                            FriendUserId = friend,
                        });
                    }

                    e.AddToUserActionsLog(ua);
                    e.SaveChanges();
                }
            }
            catch (Exception x)
            {
                if (_log.IsWarnEnabled)
                    _log.Warn("Failed to log Facebook visit", x);
            }

            // finalize
            this.Authenticated = auth;
            this.IsLoggedIn = loggedIn;
            this.UserId = uid;
            this.ViaUserId = viaUser;
            this.TimeStamp = ts;
            this.FriendsUserIds = friends;
        }
    }
}
